home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / mac / files / amiga / csrc720j.lzh / lock.c < prev    next >
C/C++ Source or Header  |  1993-01-18  |  7KB  |  248 lines

  1. /* lock.c     Handles the semaphore locking interface
  2.  
  3.    Copyright Feb. 1991, Peter Hardie VE5VA.
  4.  
  5.  
  6.    The setbusy/clrbusy/getbusy/unbusy calls are used to protect the 'GM'
  7.    and 'GU' commands so that only the sysop process running the 'GM'
  8.    can be executing at the time that the 'GM' or 'GU' proceeds.
  9.    Each process executes setbusy() when it is active and clrbusy when
  10.    it is going to sleep again (in do_idle usually). A process that
  11.    wants to do a 'GM' or 'GU' must first do a getbusy() which will either
  12.    return a value of 1 to indicate failure or otherwise it is safe to
  13.    proceed. When it has finished it must execute unbusy().
  14.    This is equivalent to the classic case of the "multiple reader -
  15.    single writer" problem.
  16.  
  17.    The begin_lock and end_lock calls are simple semaphores used to protect
  18.    write calls into the files, mail.dat, bid.mb, and user.dat. They also
  19.    protect the calls to generate the WP message and also the call to the
  20.    stale() routine. In fmsg() they lock the message currently being
  21.    forwarded.
  22.    Ideally, the locks for each file could be different which would allow
  23.    one user writing in the mail file to proceed even if another is causing
  24.    a write into the bid file (for example). I may get around to creating a
  25.    semaphore for each file once this code settles down a bit!
  26.  
  27. */
  28.  
  29.  
  30. #include <exec/types.h>
  31. #include <exec/exec.h>
  32. #include <ctype.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #include "lock.h"
  37. extern int debug;
  38. /*
  39. struct Message *lock_msg;
  40. struct MsgPort *sema_lock;
  41. */
  42. struct Message *busy_msg,*mail_msg,*user_msg,*bid_msg;
  43. struct user_sem *sema_busy;   /* Implementation of busy is a bit different
  44.                                  than for lock. user_sem is a semaphore and
  45.                                  a process counter.
  46.                               */
  47. struct file_sem *sema_mail = 0L,*sema_user = 0L, *sema_bid = 0L;
  48. /* Set up both semaphores */
  49. findlock()
  50. {
  51.    /* set up and find the semaphores for begin_lock and end_lock.
  52.       This does not need to look for the locker process as that has
  53.       already been done and we are guaranteed that it exists.
  54.    */
  55. /*
  56.    lock_msg = AllocMem(sizeof(*lock_msg), MEMF_CLEAR | MEMF_PUBLIC);
  57.    if(lock_msg == 0)return(1);
  58.    lock_msg->mn_ReplyPort = CreatePort(0L,0L);
  59.    sema_lock = FindPort(SEM_LOCK);
  60.    if(sema_lock == 0) {
  61.       stoplock();
  62.       return(1);
  63.    }
  64. */
  65.    /* set up and find the semaphore for set/clr/get/unbusy */
  66.  
  67.    busy_msg = AllocMem(sizeof(*busy_msg), MEMF_CLEAR | MEMF_PUBLIC);
  68.    if(busy_msg == 0)return(1);
  69.    busy_msg->mn_ReplyPort = CreatePort(0L,0L);
  70.    sema_busy = (struct user_sem *) FindPort(SEM_BUSY);
  71.    if(sema_busy == 0) {
  72.       stoplock();
  73.       return(2);
  74.    }
  75.    /* Create the mail.dat semaphore */
  76.    mail_msg = AllocMem(sizeof(*mail_msg), MEMF_CLEAR | MEMF_PUBLIC);
  77.    if(mail_msg == 0)return(1);
  78.    mail_msg->mn_ReplyPort = CreatePort(0L,0L);
  79.    sema_mail = (struct file_sem *) FindPort(SEM_MAIL);
  80.    if(sema_mail == 0) {
  81.       stoplock();
  82.       return(3);
  83.    }
  84.    /* Create the user.dat semaphore */
  85.    user_msg = AllocMem(sizeof(*user_msg), MEMF_CLEAR | MEMF_PUBLIC);
  86.    if(user_msg == 0)return(1);
  87.    user_msg->mn_ReplyPort = CreatePort(0L,0L);
  88.    sema_user = (struct file_sem *) FindPort(SEM_USER);
  89.    if(sema_user == 0) {
  90.       stoplock();
  91.       return(4);
  92.    }
  93.  
  94.    /* Create the bid.mb semaphore */
  95.    bid_msg = AllocMem(sizeof(*bid_msg), MEMF_CLEAR | MEMF_PUBLIC);
  96.    if(bid_msg == 0)return(1);
  97.    bid_msg->mn_ReplyPort = CreatePort(0L,0L);
  98.    sema_bid = (struct file_sem *) FindPort(SEM_BID);
  99.    if(sema_bid == 0) {
  100.       stoplock();
  101.       return(5);
  102.    }
  103.    return(0);
  104. }
  105. stoplock()
  106. {
  107. /*
  108.    if(lock_msg) {
  109.       if(lock_msg->mn_ReplyPort)DeletePort(lock_msg->mn_ReplyPort);
  110.       FreeMem(lock_msg,sizeof(*lock_msg));
  111.    }
  112. */
  113.    if(busy_msg) {
  114.       if(busy_msg->mn_ReplyPort)DeletePort(busy_msg->mn_ReplyPort);
  115.       FreeMem(busy_msg,sizeof(*busy_msg));
  116.    }
  117.    if(mail_msg) {
  118.       if(mail_msg->mn_ReplyPort)DeletePort(mail_msg->mn_ReplyPort);
  119.       FreeMem(mail_msg,sizeof(*mail_msg));
  120.    }
  121.    if(user_msg) {
  122.       if(user_msg->mn_ReplyPort)DeletePort(user_msg->mn_ReplyPort);
  123.       FreeMem(user_msg,sizeof(*user_msg));
  124.    }
  125.    if(bid_msg) {
  126.       if(bid_msg->mn_ReplyPort)DeletePort(bid_msg->mn_ReplyPort);
  127.       FreeMem(bid_msg,sizeof(*bid_msg));
  128.    }
  129. }
  130.  
  131. /* begin_lock and end_lock are not used in the multi-user CBBS any more
  132.    so make them dummy routines
  133. */
  134. begin_lock()
  135. {
  136. /*
  137.    if(Procure((struct Semaphore *)sema_lock,lock_msg) == 0) {
  138.       WaitPort(lock_msg->mn_ReplyPort);
  139.       GetMsg(lock_msg->mn_ReplyPort);
  140.    }
  141. */
  142. }
  143. end_lock()
  144. {
  145. /*
  146.    Vacate((struct Semaphore *)sema_lock);
  147. */
  148. }
  149.  
  150. setbusy()
  151. {
  152.    if(Procure((struct Semaphore *)sema_busy,busy_msg) == 0) {
  153.       WaitPort(busy_msg->mn_ReplyPort);
  154.       GetMsg(busy_msg->mn_ReplyPort);
  155.    }
  156.    sema_busy->count++;
  157.    Vacate((struct Semaphore *)sema_busy);
  158. }
  159. clrbusy()
  160. {
  161.    if(Procure((struct Semaphore *)sema_busy,busy_msg) == 0) {
  162.       WaitPort(busy_msg->mn_ReplyPort);
  163.       GetMsg(busy_msg->mn_ReplyPort);
  164.    }
  165.    sema_busy->count--;
  166.    Vacate((struct Semaphore *)sema_busy);
  167. }
  168. /* This returns 1 if there's more than one user active (itself).
  169.    The setbusy/clrbusy/getbusy/unbusy are used only to lock out users
  170.    while either a 'GM' or 'GU' are being done.
  171. */
  172. getbusy()
  173. {
  174.    if(Procure((struct Semaphore *)sema_busy,busy_msg) == 0) {
  175.       WaitPort(busy_msg->mn_ReplyPort);
  176.       GetMsg(busy_msg->mn_ReplyPort);
  177.    }
  178.    /* NOTE here that if the count is one, then we return success and
  179.       do NOT Vacate the semaphore. The process MUST call unbusy() at
  180.       a later time to clear the semaphore
  181.    */
  182.    if(sema_busy->count == 1) {
  183.       return(0);
  184.    }
  185.  
  186.    /* The count is wrong so just Vacate the semaphore and return failure
  187.    */
  188.    Vacate((struct Semaphore *)sema_busy);
  189.    return(1);
  190. }
  191.  
  192. unbusy()
  193. {
  194.    Vacate((struct Semaphore *)sema_busy);
  195. }
  196. lock_bid()
  197. {
  198.    if(Procure((struct Semaphore *)sema_bid,bid_msg) == 0) {
  199.       WaitPort(bid_msg->mn_ReplyPort);
  200.       GetMsg(bid_msg->mn_ReplyPort);
  201.    }
  202. }
  203. unlock_bid()
  204. {
  205.    Vacate((struct Semaphore *)sema_bid);
  206. }
  207. lock_user()
  208. {
  209.    if(Procure((struct Semaphore *)sema_user,user_msg) == 0) {
  210.       WaitPort(user_msg->mn_ReplyPort);
  211.       GetMsg(user_msg->mn_ReplyPort);
  212.    }
  213. }
  214. unlock_user()
  215. {
  216.    Vacate((struct Semaphore *)sema_user);
  217. }
  218. /* Process must have the semaphore already to do these next two */
  219. set_user(i)
  220. long i;
  221. {
  222.    sema_user->filesize = i;
  223. }
  224. long get_user()
  225. {
  226.    return(sema_user->filesize);
  227. }
  228. lock_mail()
  229. {
  230.    if(Procure((struct Semaphore *)sema_mail,mail_msg) == 0) {
  231.       WaitPort(mail_msg->mn_ReplyPort);
  232.       GetMsg(mail_msg->mn_ReplyPort);
  233.    }
  234. }
  235. unlock_mail()
  236. {
  237.    Vacate((struct Semaphore *)sema_mail);
  238. }
  239. set_mail(i)
  240. long i;
  241. {
  242.    sema_mail->filesize = i;
  243. }
  244. long get_mail()
  245. {
  246.    return(sema_mail->filesize);
  247. }
  248.